home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
program
/
pmtclsh.zip
/
SRC.ZIP
/
PMTCLSH.C
next >
Wrap
C/C++ Source or Header
|
1996-10-09
|
11KB
|
409 lines
/* TclSh for OS/2 ver 1.0 -- tcl shell for OS/2
* Copyright (C) 1996 Fornari Stefano
*
* Permission to use, copy, modify, and distribute this software for any
* purpose is granted without fee, provided that the above copyright notice
* and the following paragraph appear in all copies of this software
* and supporting documentation.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. In no event shall the author be
* liable to any party for direct, indirect, special, incidental, or
* consequential damages arising out of the use of this software and its
* documentation.
*/
/*-----------------------------------------------------
tclsh.c -- tcl 7.4 Interpreter for OS/2
-----------------------------------------------------*/
/*
Compiler command: gcc -Zomf -Zcrtdll tclsh.c tclsh.res tclsh.def
*/
#define INCL_WIN
#define INCL_DOS
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <io.h>
#include <os2.h>
#include "pmtclsh.h"
#ifdef WISH
#include "tkint.h"
#else
#include "tcl.h"
#endif
/* constants */
#define ENTRYHEIGHT 15
static HAB hab;
HMQ hmq;
static HWND hwndFrame = NULLHANDLE,
hwndEFInput = NULLHANDLE,
hwndMLEOutput = NULLHANDLE;
static LONG cxBorder, cyBorder, cyTitle, cyMenu;
static HFILE hOutPipe[2], hInPipe[2];
int majorVersion = 1,
minorVersion = 0;
#ifdef WISH
char szAppName [] = "Wish/2" ;
#else
char szAppName [] = "PMTclSh/2" ;
#endif
/* function prototypes */
MRESULT EXPENTRY WndProc(HWND, ULONG, MPARAM, MPARAM);
MRESULT EXPENTRY EntryProc(HWND, ULONG, MPARAM, MPARAM);
MRESULT EXPENTRY AboutProc(HWND, ULONG, MPARAM, MPARAM);
/* iscArg : looking for the presence of -c argument */
int iscArg(int argc, char **argv)
{
int i;
for(i = 1; i < argc; i++)
if(strcmp(argv[i], "-c") == 0) return 1;
return 0;
}
void ResizeControls(HWND hwndFrame, USHORT cx, USHORT cy)
{
if ((cx == 0) && (cy == 0)) return;
WinSetWindowPos(hwndEFInput, HWND_TOP, cxBorder, cyBorder,
cx-2*cxBorder, ENTRYHEIGHT,
SWP_SIZE | SWP_MOVE);
WinSetWindowPos(hwndMLEOutput, HWND_TOP, cxBorder+3, ENTRYHEIGHT+cyBorder+5,
cx-2*cxBorder-6, cy-ENTRYHEIGHT-2*cyBorder-cyTitle-cyMenu-9,
SWP_SIZE | SWP_MOVE);
}
int AskConfirmation (HWND hwnd)
{
#ifdef WISH
return WinMessageBox(HWND_DESKTOP, hwnd, "Really want to close Wish ?",
szAppName, 0, MB_YESNO | MB_ICONQUESTION);
#else
return WinMessageBox(HWND_DESKTOP, hwnd, "Really want to close PMTclShell ?",
szAppName, 0, MB_YESNO | MB_ICONQUESTION);
#endif
}
/* CreateControls
* --------------
*
* DESCRIPTION: create controls for commands input/output
*
* INPUT:
* hwndFrame frame window handle
*
* OUTPUT: TRUE if controls are correctly created, FALSE otherwise.
*
* SIDE EFFECTS: the globals variables hwndEFInput and hwndMLEOutput
* assume rispectively the windows handles for the input entry field
* and output MLE
*/
BOOL CreateControls(HWND hwndFrame)
{
SWP swp;
WinQueryWindowPos(hwndFrame, &swp);
hwndEFInput = WinCreateWindow(hwndFrame, WC_ENTRYFIELD, "",
WS_VISIBLE |WS_PARENTCLIP | ES_AUTOSCROLL | ES_MARGIN,
0, 0, 10, 10,
hwndFrame, HWND_TOP, WID_EFCOMMAND, NULL, NULL);
hwndMLEOutput = WinCreateWindow(hwndFrame, WC_MLE, "",
WS_VISIBLE | WS_PARENTCLIP | MLS_BORDER | MLS_VSCROLL |
MLS_HSCROLL | MLS_READONLY,
0, 0, 10,10,
hwndFrame, HWND_TOP, WID_EFCOMMAND, NULL, NULL);
if (hwndEFInput == NULLHANDLE || hwndMLEOutput == NULLHANDLE) return FALSE;
/* set the max input length from entry field */
WinSendMsg(hwndEFInput, EM_SETTEXTLIMIT, (MPARAM)MAXLENINPUT, 0);
return TRUE;
}
/* SourceFile
* --------------
*
* DESCRIPTION: query filname of a file that must be executed
*
* INPUT:
* hPipe pipe write handle (used to write the source command)
*
* OUTPUT:
*/
void SourceFile(HWND hwndParent, HFILE hPipe)
{
FILEDLG fdlg;
memset(&fdlg, 0, sizeof(fdlg));
fdlg.cbSize=sizeof(fdlg);
fdlg.fl = FDS_OPEN_DIALOG;
fdlg.pszTitle = "Source file";
fdlg.pszOKButton = "~Source";
strcpy(fdlg.szFullFile, "*.tcl");
if (WinFileDlg(HWND_DESKTOP, hwndParent, &fdlg))
{
char cmd[CCHMAXPATH+10]; /* it will contain 'source <filename>' */
char *p;
/* conversion \ -> / */
p = fdlg.szFullFile;
while (*p)
{
if (*p == '\\') *p = '/';
p++;
}
sprintf(cmd, "source %s\r\n", fdlg.szFullFile);
write(hPipe, cmd, strlen(cmd));
}
}
void ExitInterp(HWND hwnd, int result) {
char st[100];
sprintf(st, "Tcl interpreter exited: %d", result);
}
MRESULT EXPENTRY WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
static PFNWP pfnwp = NULL;
switch (msg)
{
case TCLSHM_PASSPARAM:
pfnwp = (PFNWP)mp1;
CreateControls(hwnd);
return (MRESULT)0;
case TCLSHM_EXITINTERP:
WinMessageBox(hwnd, HWND_DESKTOP,
"Tcl interpreter exited", szAppName,
0, MB_OK | MB_INFORMATION);
WinPostMsg(hwnd, WM_QUIT, 0, 0);
return (MRESULT)0;
case WM_WINDOWPOSCHANGED:
{
PSWP pswp = (PSWP)mp1;
ResizeControls(hwnd, pswp->cx, pswp->cy);
}; break;
case WM_INITMENU:
if (HWNDFROMMP(mp2))
{
ULONG ul;
BOOL f;
f = WinQueryClipbrdFmtInfo(hab, CF_TEXT, &ul);
WinEnableMenuItem(HWNDFROMMP(mp2), IDM_PASTE, f);
ul = (ULONG)WinSendMsg(hwndEFInput, EM_QUERYSEL, 0, 0);
f = (HIUSHORT (ul) == LOUSHORT (ul)) ? FALSE : TRUE;
WinEnableMenuItem(HWNDFROMMP(mp2), IDM_CUT, f);
WinEnableMenuItem(HWNDFROMMP(mp2), IDM_COPY, f);
WinEnableMenuItem(HWNDFROMMP(mp2), IDM_DEL, f);
return (MRESULT)0;
}
case WM_CHAR:
{
HWND hwndFocus;
hwndFocus = WinQueryFocus(HWND_DESKTOP);
if (hwndFocus == hwndEFInput || hwndFocus == hwndMLEOutput)
{
if ((CHARMSG(&msg)->fs & KC_VIRTUALKEY) &&
(CHARMSG(&msg)->fs & KC_KEYUP) &&
(CHARMSG(&msg)->vkey == VK_ENTER || CHARMSG(&msg)->vkey == VK_NEWLINE))
{
char cmdBuf[MAXLENINPUT]; /* Line buffer for commands */
LONG nLen;
nLen = WinQueryWindowText(hwndEFInput, sizeof(cmdBuf)-1, cmdBuf);
strcat(cmdBuf, "\r\n");
/* write (part of) command in the output window */
nLen = (LONG)WinSendMsg(hwndMLEOutput, MLM_QUERYTEXTLENGTH, 0, 0);
WinSendMsg(hwndMLEOutput, MLM_SETSEL, (MPARAM)nLen, (MPARAM)nLen);
WinSendMsg(hwndMLEOutput, MLM_INSERT, (MPARAM)cmdBuf, 0);
/* send the command to the interpreter */
write(hInPipe[1], cmdBuf, strlen(cmdBuf));
WinSetWindowText(hwndEFInput, "");
}
}
}; break;
case WM_COMMAND:
switch (COMMANDMSG(&msg)->cmd)
{
case IDM_EXIT:
WinSendMsg(hwnd, WM_CLOSE, 0, 0);
break;
case IDM_CUT:
{
HWND hwndFocus;
hwndFocus = WinQueryFocus(HWND_DESKTOP);
if (hwndFocus == hwndEFInput)
WinSendMsg(hwndEFInput, EM_CUT, 0, 0);
else if (hwndFocus == hwndMLEOutput)
WinSendMsg(hwndMLEOutput, MLM_CUT, 0, 0);
}; break;
case IDM_COPY:
{
HWND hwndFocus;
hwndFocus = WinQueryFocus(HWND_DESKTOP);
if (hwndFocus == hwndEFInput)
WinSendMsg(hwndEFInput, EM_COPY, 0, 0);
else if (hwndFocus == hwndMLEOutput)
WinSendMsg(hwndMLEOutput, MLM_COPY, 0, 0);
}; break;
case IDM_PASTE:
{
HWND hwndFocus;
hwndFocus = WinQueryFocus(HWND_DESKTOP);
if (hwndFocus == hwndEFInput)
WinSendMsg(hwndEFInput, EM_PASTE, 0, 0);
else if (hwndFocus == hwndMLEOutput)
WinSendMsg(hwndMLEOutput, MLM_PASTE, 0, 0);
}; break;
case IDM_DEL:
{
HWND hwndFocus;
hwndFocus = WinQueryFocus(HWND_DESKTOP);
if (hwndFocus == hwndEFInput)
WinSendMsg(hwndEFInput, EM_CLEAR, 0, 0);
else if (hwndFocus == hwndMLEOutput)
WinSendMsg(hwndMLEOutput, MLM_CLEAR, 0, 0);
}; break;
case IDM_SOURCE:
SourceFile(hwnd, hInPipe[1]);
break;
case IDM_HELP:
WinMessageBox(HWND_DESKTOP, hwnd, "Help not yet implemented!",
szAppName, 0, MB_OK | MB_ICONEXCLAMATION);
break;
case IDM_ABOUT:
if (WinDlgBox(HWND_DESKTOP, hwnd, AboutProc, NULLHANDLE, ID_ABOUTDLG, NULL)
== DID_ERROR) {
puts("Errore!"); fflush(stdout);
}; break;
}
return (MPARAM)0;
case WM_CLOSE:
if (AskConfirmation(hwnd) != MBID_YES)
return 0;
case WM_DESTROY:
DestroyInterp();
break;
}
return (*pfnwp)(hwnd, msg, mp1, mp2);
}
MRESULT EXPENTRY AboutProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
return (MRESULT)WinDefDlgProc(hwnd, msg, mp1, mp2);
}
void main(int argc, char **argv)
{
int consoleFlag;
QMSG qmsg;
ULONG ulf = FCF_STANDARD;
PFNWP pfnwp;
HFILE hFile;
APIRET rc;
char stTitle[100];
#ifdef WISH
int ret;
#endif
char st[500];
consoleFlag = iscArg(argc, argv);
hab = WinInitialize(0);
hmq = WinCreateMsgQueue(hab, 0);
cxBorder = WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER);
cyBorder = WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);
cyTitle = WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
cyMenu = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
sprintf(stTitle, "%s %d.%d", szAppName, majorVersion, minorVersion);
hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_PARENTCLIP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
&ulf, NULL, stTitle, 0, NULLHANDLE, TCLSHRC, NULL);
if (hwndFrame == NULLHANDLE)
{
WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, "Window creation error...", szAppName,
0, MB_OK | MB_ERROR);
exit(-1);
}
/* frame subclassing */
pfnwp = WinSubclassWindow(hwndFrame, (PFNWP)WndProc);
WinSendMsg(hwndFrame, TCLSHM_PASSPARAM, (MPARAM)pfnwp, 0);
WinSetWindowPos(hwndFrame, NULLHANDLE, 0, 0, 0, 0,
(consoleFlag) ? SWP_MINIMIZE : SWP_SHOW);
/* create pipes for input/output and redirict stdin, stdout, stderr */
DosCreatePipe(&hInPipe[0], &hInPipe[1], 4096);
dup2(hInPipe[0], 0); /* read stdin = read input pipe */
DosCreatePipe(&hOutPipe[0], &hOutPipe[1], 4096);
dup2(hOutPipe[1], 1); /* write stdout = write output pipe */
dup2(hOutPipe[1], 2); /* write stderr = write output pipe */
if (!CreateInterp(hwndFrame, hwndMLEOutput, hOutPipe[0]))
{
WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, "Interpreter creation error...", szAppName,
0, MB_OK | MB_ERROR);
exit(-3);
}
while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
WinDispatchMsg(hab, &qmsg);
WinDestroyWindow(hwndFrame);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
}